package com.code.generator.code.impl;


import com.code.generator.context.velocity.VelocityGeneratorContext;
import com.code.entity.GenerateDescriptor;
import com.code.exception.CodeGenerateException;
import com.code.generator.provider.CodeGenerateProvider;
import com.code.enums.CodeGenerateProviderType;
import com.code.enums.CodeGenerateType;

import java.io.IOException;
import java.util.List;
import java.util.stream.Stream;

public final class CodeGenerateManager {

    private CodeGenerateManager() {

    }

    private static String prefixOfTable = "t_";

    public static void setPrefixOfTable(String prefix) {
        CodeGenerateManager.prefixOfTable = prefix;
    }


    public static void generate(CodeGenerateProviderType providerType, List<GenerateDescriptor> descriptors) {
        switch (providerType) {
            case VELOCITY:
                doGenerateUsingVelocity(descriptors);
                break;
            default:
                throw new CodeGenerateException("不支持的生成策略!");
        }
    }

    private static void doGenerateUsingVelocity(List<GenerateDescriptor> descriptors) {
        if (descriptors == null || descriptors.isEmpty()) {
            return;
        }
        descriptors.forEach(descriptor -> {
            System.out.println("开始生成 " + descriptor.getModule() +
                    "->" + descriptor.getTable().getName() + " -------------------------->");
            final VelocityGeneratorContext context = new VelocityGeneratorContext(descriptor, prefixOfTable);
            final CodeGenerateProvider provider = new CodeGenerateProvider();

            CodeGenerateType[] generateTypes = descriptor.getGenerateTypes();
            if (generateTypes != null) {
                Stream.of(generateTypes).forEach(generateType -> {
                    System.out.println("开始生成 " + descriptor.getModule() +
                            " -> " + descriptor.getTable().getName() + " -> "
                            + generateType.getName() + " -------------------------->");
                    try {
                        switch (generateType) {
                            case PERSISTENCE:
                                provider.generatePersistence(context);
                                break;
                            case MODEL:
                                provider.generateModel(context);
                                break;
                            case FILTER:
                                provider.generateFilter(context);
                                break;
                            case ENTITY:
                                provider.generateEntity(context);
                                break;
                            case MAPPER:
                                provider.generateMapper(context);
                                break;
                            case MAPPER_XML:
                                provider.generateMapperXml(context);
                                break;
                            case REPOSITORY:
                                provider.generateRepository(context);
                                break;
                            case REPOSITORY_IMPL:
                                provider.generateRepositoryImpl(context);
                                break;
                            case SERVICE:
                                provider.generateService(context);
                                break;
                            case SERVICE_IMPL:
                                provider.generateServiceImpl(context);
                                break;
                            case REQUEST:
                                provider.generateRequest(context);
                                break;
                            case QUERY_REQUEST:
                                provider.generateQueryRequest(context);
                                break;
                            case PAGINATION_REQUEST:
                                provider.generatePaginationRequest(context);
                                break;
                            case CONTROLLER:
                                provider.generateController(context);
                                break;
                            case API_JS:
                                provider.generateApiJs(context);
                                break;
                            case INDEX:
                                provider.generateIndex(context);
                                break;
                        }
                    } catch (IOException e) {
                        throw new CodeGenerateException("代码生成失败!", e);
                    }
                });
            }
        });
    }
}
